using System;
using System.Security.Cryptography;
using System.Text;

namespace Saffron.Framework.Users
{
    public static class UserServices
    {
        internal static string HashPassword(string password, int salt)
        {
            ASCIIEncoding encoder = new ASCIIEncoding();
            Byte[] secretBytes = encoder.GetBytes(password);

            // Create a new salt
            Byte[] saltBytes = new Byte[4];
            saltBytes[0] = (byte)(salt >> 24);
            saltBytes[1] = (byte)(salt >> 16);
            saltBytes[2] = (byte)(salt >> 8);
            saltBytes[3] = (byte)(salt);

            // append the two arrays
            Byte[] toHash = new Byte[secretBytes.Length + saltBytes.Length];
            Array.Copy(secretBytes, 0, toHash, 0, secretBytes.Length);
            Array.Copy(saltBytes, 0, toHash, secretBytes.Length, saltBytes.Length);

            SHA1 sha1 = SHA1.Create();
            Byte[] computedHash = sha1.ComputeHash(toHash);

            return encoder.GetString(computedHash);
        }

        internal static int GetRandomSalt()
        {
            Byte[] _saltBytes = new Byte[4];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(_saltBytes);

            return ((((int)_saltBytes[0]) << 24) + (((int)_saltBytes[1]) << 16) +
              (((int)_saltBytes[2]) << 8) + ((int)_saltBytes[3]));
        }

        public static UserAccount ValidateLogin(string userName, string password)
        {
            UserAccount user = UserAccount.FindByLoginName(userName);

            if (user == null)
                throw new System.Security.SecurityException("Invalid login name: " + userName);

            string hashed = HashPassword(password, user.PasswordSalt);

            if (string.Compare(hashed, user.PasswordHash, false) != 0)
                throw new System.Security.SecurityException("Invalid password");

            return user;
        }

        public static UserAttributeGroup CreateNewUserAttributeGroup(string name)
        {
            UserAttributeGroup attribute = new UserAttributeGroup();
            attribute.Name = name;
            attribute.Create();
            return attribute;
        }

        public static UserAttribute CreateNewUserAttribute(string name, UserAttributeGroup group)
        {
            UserAttribute attribute = new UserAttribute();
            attribute.Name = name;
            attribute.Group = group;
            attribute.Create();
            return attribute;
        }

        
    }
}
